package dk.sdu.flexibus.persistence;

import java.util.ArrayList;
import java.util.List;

import android.content.SharedPreferences;
import dk.sdu.flexibus.domain.Transport;

public class TransportFactory {
	private static final String KEY_SERVER_ID = "KEY_SERVER_ID";
	private static final String KEY_TRANSPORT_STATE = "KEY_TRANSPORT_STATE";
	private static final String KEY_PICKUP_TIME = "KEY_PICKUP_TIME";
	private static final String KEY_PICKUP_ADDRESS = "KEY_PICKUP_ADDRESS";
	private static final String KEY_DROPOFF_TIME = "KEY_DROPOFF_TIME";
	private static final String KEY_DROPOFF_PLACE = "KEY_DROPOFF_PLACE";

	private static final String TRANSPORT_ID_COUNTER = "TRANSPORT_ID_COUNTER";

	public static int getMaxId(SharedPreferences preferences){
		return preferences.getInt(TRANSPORT_ID_COUNTER, 0)-1;
	}
	
	private static int getNextId(SharedPreferences preferences){
		return Persister.getNextId(preferences, TRANSPORT_ID_COUNTER);
	}
	
	static long readLong(SharedPreferences preferences, int id, String field, long defaultValue){
		long longResult = preferences.getLong(""+id+field, Long.MIN_VALUE);
		if(longResult == Long.MIN_VALUE){
			return defaultValue;
		}
		return longResult;
	}
	
	public static Transport getNewInstance(SharedPreferences preferences){
		Transport newInstance = new Transport();
		newInstance.setId(getNextId(preferences));
		newInstance.setTransportState(Transport.STATE_CREATED);
		return newInstance;
	}
	
	public static Transport readTransport(SharedPreferences preferences, int id){
		if(id>getMaxId(preferences)){
			return null;
		}
		Transport instance = new Transport();
		instance.setId(id);
		instance.setServerId(Persister.readInt(preferences, id, KEY_SERVER_ID, Transport.SERVER_ID_UNDEFINED));
		instance.setTransportState(Persister.readInt(preferences, id, KEY_TRANSPORT_STATE, Transport.STATE_UNDEFINED));
		instance.setPickupAddress(Persister.readString(preferences, id, KEY_PICKUP_ADDRESS, null));
		instance.setDropOffPlace(Persister.readString(preferences, id, KEY_DROPOFF_PLACE, null));
		instance.setPickupTime(Persister.readCalendar(preferences, id, KEY_PICKUP_TIME, null));
		instance.setDropOffTime(Persister.readCalendar(preferences, id, KEY_DROPOFF_TIME, null));
		return instance;
	}
	
	public static int writeTransport(SharedPreferences preferences, Transport transport){
		//validate
		if(transport.getId() == Transport.KEY_UNDEFINED){
			return -1;
		}
		
		//write
		Persister.writeInt(preferences, transport.getId(), KEY_SERVER_ID, transport.getServerId());
		Persister.writeInt(preferences, transport.getId(), KEY_TRANSPORT_STATE, transport.getTransportState());
		Persister.writeString(preferences, transport.getId(), KEY_PICKUP_ADDRESS, transport.getPickupAddress());
		Persister.writeString(preferences, transport.getId(), KEY_DROPOFF_PLACE, transport.getDropOffPlace());
		Persister.writeCalendar(preferences, transport.getId(), KEY_PICKUP_TIME, transport.getPickupTime());
		Persister.writeCalendar(preferences, transport.getId(), KEY_DROPOFF_TIME, transport.getDropOffTime());
		return 0;
	}
	
	public static List<Integer> findTransportIdsByState(SharedPreferences preferences, int[] states){
		int maxId = getMaxId(preferences);
		ArrayList<Integer> results = new ArrayList<Integer>();
		for(int i = 0; i <= maxId; i++){
			int state = Persister.readInt(preferences, i, KEY_TRANSPORT_STATE, Transport.STATE_UNDEFINED);
			for(int j = 0; j < states.length; j++){
				if(state == states[j]){
					results.add(i);
				}
			}
		}
		return results;
	}

	public static int findTransportIdsByServerId(SharedPreferences preferences, int desiredId){
		int maxId = getMaxId(preferences);
		for(int i = 0; i <= maxId; i++){
			int currentServerId = Persister.readInt(preferences, i, KEY_SERVER_ID, Transport.SERVER_ID_UNDEFINED);
			if(currentServerId == desiredId){
				return i;
			}
		}
		return Transport.SERVER_ID_UNDEFINED;
	}
	
	public static List<Transport> getAllTransports(SharedPreferences preferences){
		int maxId = getMaxId(preferences);
		ArrayList<Transport> results = new ArrayList<Transport>();
		for(int i = 0; i <= maxId; i++){
			Transport t = readTransport(preferences, i);
			results.add(t);
		}
		return results;
	}
}
